package cn.sciento.core.endpoint.request;

import java.util.Map;
import cn.sciento.core.endpoint.HttpRequest;
import cn.sciento.core.util.ServiceInstanceUtils;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.util.MultiValueMap;

public class StaticEndpointHttpRequest<T> implements HttpRequest<T> {
  private final HttpHeaders headers = new HttpHeaders();
  
  private ServiceInstance instance;
  
  private StaticEndpoint endpoint;
  
  private Map<String, String> requestParams;
  
  private HttpEntity<byte[]> httpEntity;
  
  private Class<T> responseClass;
  
  private boolean enableSsl;
  
  public StaticEndpointHttpRequest(ServiceInstance instance, StaticEndpoint endpoint, Map<String, String> requestParams, byte[] requestBody, Class<T> responseClass, boolean enableSsl) {
    this.headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
    this.instance = instance;
    this.endpoint = endpoint;
    this.requestParams = requestParams;
    this.httpEntity = new HttpEntity(requestBody, this.headers);
    this.responseClass = responseClass;
    this.enableSsl = enableSsl;
  }
  
  public StaticEndpointHttpRequest(ServiceInstance instance, StaticEndpoint endpoint, Class<T> responseClass) {
    this(instance, endpoint, null, null, responseClass, false);
  }
  
  public StaticEndpointHttpRequest(ServiceInstance instance, StaticEndpoint endpoint, Map<String, String> requestParams, Class<T> responseClass) {
    this(instance, endpoint, requestParams, null, responseClass, false);
  }
  
  public StaticEndpointHttpRequest(ServiceInstance instance, StaticEndpoint endpoint, byte[] requestBody, Class<T> responseClass) {
    this(instance, endpoint, null, requestBody, responseClass, false);
  }
  
  @Override
  public String getSchema() {
    return this.enableSsl ? "https://" : "http://";
  }
  
  @Override
  public String getUrl() {
    return this.instance.getHost() + ":" + (
      this.endpoint.isUseManagementPort() ? ServiceInstanceUtils.getManagementPortFromMetadata(this.instance) : (this.instance.getPort() + ServiceInstanceUtils.getContextFromMetadata(this.instance))) + this.endpoint
      .getEndpoint() + 
      toString(this.requestParams);
  }
  
  @Override
  public HttpMethod getMethod() {
    return this.endpoint.getMethod();
  }
  
  @Override
  public HttpEntity<byte[]> getHttpEntity() {
    return this.httpEntity;
  }
  
  @Override
  public Class<T> getResponseClass() {
    return this.responseClass;
  }
}
